﻿using System;
using NHibernate.Event;
using NHibernate.Persister.Entity;

namespace ECommerce.Web.NHibernate.EventListeners
{
    public class ChangeConflictEventListener : IPreUpdateEventListener
    {
        private static Func<string> DefaultChangeConflictFormatter =
            () => "Your changes could not be saved because another user has since made an update.";
        
        private Func<string> changeConflictFormatter;

        public Func<string> ChangeConflictFormatter
        {
            get { return this.changeConflictFormatter ?? DefaultChangeConflictFormatter; }
            set { this.changeConflictFormatter = value; }
        }
        
        public bool OnPreUpdate(PreUpdateEvent preUpdateEvent)
        {
            IEntityPersister persister = preUpdateEvent.Persister;

            if (persister.IsVersioned)
            {
                object currentVersion = persister.GetCurrentVersion(preUpdateEvent.Id, preUpdateEvent.Session.GetSessionImplementation());

                object version = persister.GetVersion(preUpdateEvent.Entity, preUpdateEvent.Session.EntityMode);

                if (!persister.VersionType.IsEqual(currentVersion, version))
                {
                    throw new ChangeConflictException(DefaultChangeConflictFormatter());
                }
            }

            return false;
        }
    }
}
